package com.bn.feeds.utils;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import au.com.bytecode.opencsv.CSVReader;


/**
 * The Class ParseUtils.
 * @author Abhishek
 */
public class TruParseUtils extends ParseUtils {

	private char feedColumnSeperator = '^';

	private char quotechar;

	public char getFeedColumnSeperator() {
		return feedColumnSeperator;
	}


	public void setFeedColumnSeperator(char feedColumnSeperator) {
		this.feedColumnSeperator = feedColumnSeperator;
	}


	/**
	 * Parses a given file.
	 *
	 * @param file
	 *            the file
	 * @param fileType
	 *            the file type
	 * @return the map
	 */
	public Map<String, List<String[]>> parseFile(File file, String fileType){
		if(fileType.equalsIgnoreCase("CSV")){
			return getCSVData(file);
		}else if(fileType.equalsIgnoreCase("XML")){
			//TODO - call method for parsing xml
			if(isLoggingDebug()){
				logDebug("No XML feed yet");
			}
		}
		return null;
	}

	public Map<String, List<String[]>> parseFile(File file, String fileType,boolean noHeader){
		
		if(!noHeader){
			parseFile(file, fileType);
		} else {
			if(fileType.equalsIgnoreCase("CSV")){
				return getCSVDataWithNoHeader(file);
			}else if(fileType.equalsIgnoreCase("XML")){
				//TODO - call method for parsing xml
				if(isLoggingDebug()){
					logDebug("No XML feed yet");
				}
			}
		}
		
		return null;
	}


	/**
	 * It returns Map(Map<String, List<String[]>>) of data from a given CSV file.
	 * Ex. Map<header, List of header data>
	 *
	 * @param dataFile
	 *            the data file
	 * @return the cSV data
	 */
	public Map<String, List<String[]>> getCSVData(File dataFile) {

		Map<String, List<String[]>> dataMap = null;
		CSVReader csvReader = null;
		List<String[]> csvData = null;

		try {
			if (dataFile != null) {
			    InputStreamReader reader = new InputStreamReader(new FileInputStream(dataFile), Charset.forName("UTF-8"));
			    if(getQuotechar() == '"'){
			    	csvReader = new CSVReader(reader, feedColumnSeperator, getQuotechar(), '\0', 0, false, false);
			    }else{
			    	csvReader = new CSVReader(reader, feedColumnSeperator, '\0', '\0', 0, false, false);
			    }
				csvData = csvReader.readAll();

				if (csvData.size() > 1) {
					dataMap = new HashMap<String, List<String[]>>();
					List<String[]> header = new ArrayList<String[]>();

					String[] headerData = csvData.get(1);
					for (int index =0; index < headerData.length; index++){
					    headerData[index] = headerData[index].toLowerCase();
					    System.out.println("@@@@@@@ "+index +" : "+headerData[index]);
					}

					header.add(headerData);
                    csvData.remove(0);
                    csvData.remove(0);
                    csvData.remove(csvData.size()-1);

					dataMap.put("header", header);
					dataMap.put("data", csvData);
				} else {
					if (isLoggingDebug()){
						logDebug("File ("+ dataFile.getAbsolutePath() +") is empty or contains just header");
					}
				}


			} else {
				if (isLoggingDebug()){
					logDebug("Recieved null file dataFile");
				}
			}

		} catch (FileNotFoundException e) {
			if (isLoggingError()){
				logError("Exception occurred while reading the file:" + dataFile.getAbsolutePath(), e);
			}
		} catch (IOException e) {
			if (isLoggingError()){
				logError("Exception occurred while reading the file:" + dataFile.getAbsolutePath(), e);
			}
		}finally{
			if(csvReader!=null)
				try {
					csvReader.close();
				} catch (IOException e) {
					if(isLoggingError())
						logError("Exception occured while closeing csv reader: "+csvReader, e);
				}
		}

		return dataMap;
	}

	public Map<String, List<String[]>> getCSVDataWithNoHeader(File dataFile) {

		Map<String, List<String[]>> dataMap = null;
		CSVReader csvReader = null;
		List<String[]> csvData = null;

		try {
			if (dataFile != null) {
			    InputStreamReader reader = new InputStreamReader(new FileInputStream(dataFile), Charset.forName("UTF-8"));
			    if(getQuotechar() == '"'){
			    	csvReader = new CSVReader(reader, feedColumnSeperator, getQuotechar(), '\0', 0, false, false);
			    }else{
			    	csvReader = new CSVReader(reader, feedColumnSeperator, '\0', '\0', 0, false, false);
			    }
				csvData = csvReader.readAll();

				if (csvData.size() > 1) {
					dataMap = new HashMap<String, List<String[]>>();
					List<String[]> header = new ArrayList<String[]>();

					String[] headerData = csvData.get(0);
					for (int index =0; index < headerData.length; index++){
					    headerData[index] = headerData[index].toLowerCase();
					    System.out.println("@@@@@@@ "+index +" : "+headerData[index]);
					}
					header.add(headerData);
					csvData.remove(0);
					dataMap.put("header", header);
					dataMap.put("data", csvData);
				} else {
					if (isLoggingDebug()){
						logDebug("File ("+ dataFile.getAbsolutePath() +") is empty or contains just header");
					}
				}


			} else {
				if (isLoggingDebug()){
					logDebug("Recieved null file dataFile");
				}
			}

		} catch (FileNotFoundException e) {
			if (isLoggingError()){
				logError("Exception occurred while reading the file:" + dataFile.getAbsolutePath(), e);
			}
		} catch (IOException e) {
			if (isLoggingError()){
				logError("Exception occurred while reading the file:" + dataFile.getAbsolutePath(), e);
			}
		}finally{
			if(csvReader!=null)
				try {
					csvReader.close();
				} catch (IOException e) {
					if(isLoggingError())
						logError("Exception occured while closeing csv reader: "+csvReader, e);
				}
		}

		return dataMap;
	}

	public char getQuotechar() {
		return quotechar;
	}


	public void setQuotechar(char quotechar) {
		this.quotechar = quotechar;
	}
}
